package com.example.musicplayer.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;

import com.example.musicplayer.R;

public class LyricFeaturesScrollView extends HorizontalScrollView {
    //是否启用边缘滑动
    private boolean mEnable = true;
    //表示是否为手指按压状态
    private boolean mPressed = false;
    private boolean mFlag = false;
    //记录手指按下时的x坐标
    private int mStartX;
    //记录手指按下时的getScrollX()
    private int mScrollX;
    //记录内容滚动距离的最小值和最大值
    private int mMin;
    private int mMax;
    private static final String TAG = "LyricFeaturesScrollView";

    public LyricFeaturesScrollView(Context context) {
        super(context);
    }

    public LyricFeaturesScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public LyricFeaturesScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        initView();
    }

    //是否启用边缘滑动
    public boolean setEnable(boolean flag) {
        mEnable = flag;
        return mEnable;
    }

    //初始化scrollview，滚动到开头
    private void initView() {
        mStartX = mScrollX = -1;
        mMin = (int) getResources().getDimension(R.dimen.fragment_lyric_features_dialog_buffer_width);
        mMax = getChildAt(getChildCount() - 1).getRight() + getPaddingRight() - getWidth() - mMin;
        scrollToStart();
    }

    @Override
    protected void onScrollChanged(int x, int y, int oldX, int oldY) {
        super.onScrollChanged(x, y, oldX, oldY);
        if (!mPressed) {
            if (x <= mMin)
                scrollToStart();
            if (x >= mMax)
                scrollToEnd();
        }
    }

    @Override
    public boolean performClick() {
        return super.performClick();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!mEnable)
            return super.onTouchEvent(event);
        int x = (int) event.getX();
        if (mStartX < 0) {
            mStartX = x;
            mScrollX = getScrollX();
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mPressed = true;
                performClick();
                break;
            case MotionEvent.ACTION_MOVE:
                mPressed = true;
                shouldScroll(x);
                if (mFlag)
                    return true;
                break;
            case MotionEvent.ACTION_UP:
                mPressed = false;
                mStartX = mScrollX = -1;
                if (getScrollX() < mMin)
                    scrollToStart();
                if (getScrollX() > mMax)
                    scrollToEnd();
                break;
        }
        return super.onTouchEvent(event);
    }

    //滚动到内容的开始位置
    private void scrollToStart() {
        scrollTo(mMin, 0);
    }

    //滚动到内容的结束位置
    private void scrollToEnd() {
        scrollTo(mMax, 0);
    }

    //计算应该滚动到的位置
    private void shouldScroll(int x) {
        if (x != mStartX && mStartX >= 0) {
            int position = mMin;
            int dx = x - mStartX;
            if (dx < 0) {
                if (-dx <= mMax - mScrollX) {
                    position = mScrollX - dx;
                    mFlag = false;
                } else {
                    position = mMax + changeToScrollDistance(-dx - mMax + mScrollX);
                    mFlag = true;
                }
            } else {
                if (dx <= mScrollX - mMin) {
                    position = mScrollX - dx;
                    mFlag = false;
                } else {
                    position = mMin - changeToScrollDistance(dx - mScrollX + mMin);
                    mFlag = true;
                }
            }
            scrollTo(position, 0);
        }
    }

    //将手指滑动距离转为内容滑动距离
    private int changeToScrollDistance(int moveDistance) {
        double distance = Math.pow(moveDistance, 0.9);
        return (int) distance;
    }
}